// 手写vue3中采用的api
let reactivehandle = {
  get(target, props) {
    if (props == '_is_reactive') return true;
    console.log('reactive读取了', target, props);
    return Reflect.get(target, props);
  },
  set(target, props, val) {
    console.log('reactive设置了', props, val);
    Reflect.set(target, props, val);
    return true;
  },
  deleteProperty(target, props) {
    console.log('reactive删除了', props);
    let res = Reflect.deleteProperty(target, props);
    return res;
  }
}
// 1. shallowReactive(浅劫持、浅监视)、reactive(深劫持)
function shallowReactive(target:object):object {
  if (target && typeof target == 'object') {
    return new Proxy(target, reactivehandle);
  }
}

function reactive(target:object):object {
  if (target && typeof target == 'object') {
    if (Array.isArray(target)) {
      target.forEach((item, index) => {
        // 递归
        target[index] = reactive(item);
      })
    }
    else {
      Object.keys(target).forEach((item, index) => {
        target[item] = reactive(target[item]);
      })
    }
    return new Proxy(target, reactivehandle);
  }
}

// shallowReadonly和readnly
let readonlyhandle = {
  get(target, props) {
    if (props == '_is_readonly') return true;
    console.log('readonly读取了', target, props);
    return Reflect.get(target, props);
  },
  set(target, props, val) {
    console.warn('readonly是只读的，不支持修改数据');
    return true;
  },
  deleteproperty(target, props) {
    console.warn('readonly是只读的，不支持删除数据');
    return true;
  }
}
function shallowReadonly(target: object) {
  if (target && typeof target === 'object') {
    return new Proxy(target, readonlyhandle)
  } 
}

function readonly(target:object) {
  if (target && typeof target === 'object') {
    if (Array.isArray(target)) {
      target.forEach((item, idx) => {
        target[idx] = readonly(item);
      })
    }
    else {
      Object.keys(target).forEach(key => {
        target[key] = readonly(target[key]);
      })
    }
    return new Proxy(target, readonlyhandle)
  } 
}

// 3. shallowRef 和ref
function shallowRef(target:any) {
  return {
    _value: target,
    get value() {
      console.log('shallowRef读取数据');
      return this._value;
    },
    set value(val) {
      console.log('shallowRef修改数据');
      this._value = val;
    }
  }
}


function ref(target: any) {
  target = reactive(target);
  return {
    _is_ref: true,// 标记ref对象
    _value: target,
    get value() {
      console.log('ref读取数据');
      return this._value;
    },
    set value(val) {
      console.log('ref修改数据');
      this._value = val;
    }
  }
}

// 4.isRef、isReactive、isProxy，isReadonly
function isRef(target:any) {
  return target && target._is_ref;
}

function isReactive(target:any) {
  return target && target._is_reactive;
}

function isReadonly(target:any) {
  return target && target._is_readonly;
}

function isProxy(target:any) {
  return isReadonly(target) || isReactive(target);
}